use super::{update_map, Data};
use leptos::*;
use std::{collections::HashMap, rc::Rc};

#[allow(non_snake_case)]
#[component]
pub fn Input(
    label: &'static str,
    #[prop(into)] name: String,
    #[prop(optional, default = false)] hidden: bool,
) -> impl IntoView {
    let (getter, setter) = use_context::<(
        ReadSignal<HashMap<String, Data>>,
        WriteSignal<HashMap<String, Data>>,
    )>()
    .expect("to have found the setter provided");
    let name = Rc::new(name);
    let value = {
        let name = Rc::clone(&name);
        move || {
            let map = getter.get();
            let str = map.get(name.as_str()).and_then(|v| v.str());
            str.map(|v| v.to_string()).unwrap_or_default()
        }
    };
    view! {
        <div
            class="flex flex-col gap-1 py-2"
            class:hidden=hidden
        >
            <label class="pl-2 text-lg">{label}":"</label>
            <input
                class="border-solid border rounded h-9 outline-blue-400 pl-2"
                value = move || {value()}
                type="text"
                on:change=move |ev| {
                    let name = name.as_ref();
                    let val = event_target_value(&ev);
                    setter
                        .update(|map| {
                            if name.contains('.') {
                                update_map(name, val, map);
                            } else {
                                let name = name.to_string();
                                let val = Data::String(val);
                                map.insert(name, val);
                            }
                        })
                }
            />
        </div>
    }
}
